﻿namespace WebPacker.Tool.Tests
{
	using System;
	using NUnit.Framework;
	using WebPacker.Filters;
	using WebPacker.Tool.Tests.EqualityComparers;
	using WebPacker.VersionGenerators;

	[TestFixture]
	public class ConfigurationTest
	{
		[Test]
		public void OpenDefaultConfigurationTest()
		{
			var actual = Configuration.OpenConfiguration(null);
			AssertConfiguraionEquals(GetDefaultConfiguration(), actual);
		}

		[Test]
		public void OpenStandartConfigurationTest()
		{
			var actual = Configuration.OpenConfiguration("samples/defaults.xml");
			AssertConfiguraionEquals(GetDefaultConfiguration(), actual);
		}

		[Test]
		public void OpenCustomConfigurationTest()
		{
			var actual = Configuration.OpenConfiguration("samples/custom.xml");

			var expected = new Configuration
			{
				Output = "build",
				VersionGeneratorName = "md5",
				Filters = new IFilter[]
				{
					new YuiCssMinifier(),
					new YuiJavascriptMinifier { IsObfuscateJavascript = false }
				},
				VersionGenerators = new IVersionGenerator[]
				{
					new Md5VersionGenerator()
				}
			};

			AssertConfiguraionEquals(expected, actual);
		}

		internal static void AssertConfiguraionEquals(Configuration expected, Configuration actual)
		{
			if (Object.ReferenceEquals(expected, actual))
			{
				return;
			}

			if (expected == null)
			{
				Assert.IsNull(actual);
				return;
			}

			Assert.IsNotNull(actual);
			Assert.AreEqual(expected.BasePath, actual.BasePath);
			Assert.AreEqual(expected.Output, actual.Output);
			Assert.AreEqual(expected.VersionGeneratorName, actual.VersionGeneratorName);

			if (expected.Filters != null)
			{
				Assert.IsNotNull(actual.Filters);
				Assert.That(actual.Filters, Is.EquivalentTo(expected.Filters).Using(new FilterEqualityComparer()));
			}
			else
			{
				Assert.IsNull(actual.Filters);
			}

			if (expected.VersionGenerators != null)
			{
				Assert.IsNotNull(actual.VersionGenerators);
				Assert.That(actual.VersionGenerators, Is.EquivalentTo(expected.VersionGenerators).Using(new VersionGeneratorEqualityComparer()));
			}
			else
			{
				Assert.IsNull(actual.VersionGenerators);
			}
		}

		private static Configuration GetDefaultConfiguration()
		{
			return new Configuration
			{
				Filters = new IFilter[]
				{
					new YuiCssMinifier { Name = "css" },
					new YuiJavascriptMinifier { Name = "js" }
				},
				VersionGenerators = new IVersionGenerator[]
				{
					new Md5VersionGenerator(),
					new LastModifiedVersionGenerator(),
					new ManualVersionGenerator(),
					new HashCodeVersionGenerator()
				},
				VersionGeneratorName = "manual"
			};
		}
	}
}
